#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include "ladspa.h"


#define KARAOKE_INPUT1 0
#define KARAOKE_INPUT2 1
#define KARAOKE_OUTPUT 2


typedef struct{
  LADSPA_Data * m_pfInputBuffer1;
  LADSPA_Data * m_pfInputBuffer2;
  LADSPA_Data * m_pfOutputBuffer;
} Karaoke;


/*--------------------------------------------------------------*/

LADSPA_Handle 
instantiateKaraoke(const LADSPA_Descriptor * Descriptor,
		     unsigned long             SampleRate) {
  return malloc(sizeof(Karaoke));
}

/*--------------------------------------------------------------*/

void 
connectPortToKaraoke(LADSPA_Handle Instance, unsigned long Port,
		       LADSPA_Data * DataLocation) {
  Karaoke * psKaraoke;
  psKaraoke = (Karaoke *)Instance;
  switch (Port) {
  case KARAOKE_INPUT1:
    psKaraoke->m_pfInputBuffer1 = DataLocation;
    break;
  case KARAOKE_INPUT2:
    psKaraoke->m_pfInputBuffer2 = DataLocation;
    break;
  case KARAOKE_OUTPUT:
    psKaraoke->m_pfOutputBuffer = DataLocation;
    break;
  }
}

/*--------------------------------------------------------------*/

void 
runKaraoke(LADSPA_Handle Instance,
		     unsigned long SampleCount) {

  Karaoke * psKaraoke = (Karaoke *)Instance;
  LADSPA_Data * pfInput1;
  LADSPA_Data * pfInput2;
  LADSPA_Data * pfOutput;
  printf("ok\n");
  pfInput1 = psKaraoke->m_pfInputBuffer1;
  printf("ok\n");
  pfInput2 = psKaraoke->m_pfInputBuffer2;
  printf("ok\n");
  pfOutput = psKaraoke->m_pfOutputBuffer;
  printf("ok\n");
  unsigned long i;
  for( i=0; i < SampleCount; i++)
    pfOutput[i] = pfInput1[i] - pfInput2[i];
 printf("ok\n");
}

/*--------------------------------------------------------------*/

void 
cleanupKaraoke(LADSPA_Handle Instance) {
  free(Instance);
}

/*--------------------------------------------------------------*/
LADSPA_Descriptor * g_psKaraoke = NULL;

void 
_init() {

  char ** pcPortNames;
  LADSPA_PortDescriptor * piPortDescriptors;
  LADSPA_PortRangeHint * psPortRangeHints;

  g_psKaraoke
    = (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));

  
    g_psKaraoke->UniqueID = 9999;
    g_psKaraoke->Label = strdup("karaoke");
    g_psKaraoke->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
    g_psKaraoke->Name = strdup("Mono karaoke");
    g_psKaraoke->Maker = strdup("Momsse (LADSPA example plugins)");
    g_psKaraoke->Copyright = strdup("None");
    g_psKaraoke->PortCount= 3;

    piPortDescriptors = (LADSPA_PortDescriptor *)calloc(3, sizeof(LADSPA_PortDescriptor));
    g_psKaraoke->PortDescriptors = (const LADSPA_PortDescriptor *)piPortDescriptors;
    piPortDescriptors[KARAOKE_INPUT1] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
    piPortDescriptors[KARAOKE_INPUT2] = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
    piPortDescriptors[KARAOKE_OUTPUT] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;

    pcPortNames = (char **)calloc(3, sizeof(char *));

    g_psKaraoke->PortNames = (const char **)pcPortNames;
    pcPortNames[KARAOKE_INPUT1] = strdup("ENTREE1");
    pcPortNames[KARAOKE_INPUT2] = strdup("ENTREE2");
    pcPortNames[KARAOKE_OUTPUT] = strdup("Output");

    psPortRangeHints = ((LADSPA_PortRangeHint *)calloc(3, sizeof(LADSPA_PortRangeHint)));

    g_psKaraoke->PortRangeHints = (const LADSPA_PortRangeHint *)psPortRangeHints;
    psPortRangeHints[KARAOKE_INPUT1].HintDescriptor  = (LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_LOGARITHMIC
							                          | LADSPA_HINT_DEFAULT_1);
    psPortRangeHints[KARAOKE_INPUT1].HintDescriptor  = 0;
    psPortRangeHints[KARAOKE_INPUT2].HintDescriptor  = 0;
    psPortRangeHints[KARAOKE_OUTPUT].HintDescriptor  = 0;

    g_psKaraoke->instantiate  = instantiateKaraoke;
    g_psKaraoke->connect_port = connectPortToKaraoke;
    g_psKaraoke->activate  = NULL;
    g_psKaraoke->run = runKaraoke;
    g_psKaraoke->run_adding = NULL;
    g_psKaraoke->set_run_adding_gain = NULL;
    g_psKaraoke->deactivate = NULL;
    g_psKaraoke->cleanup = cleanupKaraoke;
 
}

/*--------------------------------------------------------------*/

void
deleteDescriptor(LADSPA_Descriptor * psDescriptor) {
  unsigned long lIndex;
  if (psDescriptor) {
    free((char *)psDescriptor->Label);
    free((char *)psDescriptor->Name);
    free((char *)psDescriptor->Maker);
    free((char *)psDescriptor->Copyright);
    free((LADSPA_PortDescriptor *)psDescriptor->PortDescriptors);
    for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
      free((char *)(psDescriptor->PortNames[lIndex]));
    free((char **)psDescriptor->PortNames);
    free((LADSPA_PortRangeHint *)psDescriptor->PortRangeHints);
    free(psDescriptor);
  }
}

/*--------------------------------------------------------------*/

void
_fini() {
  deleteDescriptor(g_psKaraoke);
}

const LADSPA_Descriptor * 
ladspa_descriptor(unsigned long Index) {
  if(Index == 0)
    return g_psKaraoke;
  else
    return NULL;
}
